(function() { "use strict";
/**
 * 0.1.1
 * General-purpose jQuery wrapper. Simply pass the plugin name as the expression.
 *
 * It is possible to specify a default set of parameters for each jQuery plugin.
 * Under the jq key, namespace each plugin by that which will be passed to ui-jq.
 * Unfortunately, at this time you can only pre-define the first parameter.
 * @example { jq : { datepicker : { showOn:'click' } } }
 *
 * @param ui-jq {string} The $elm.[pluginName]() to call.
 * @param [ui-options] {mixed} Expression to be evaluated and passed as options to the function
 *     Multiple parameters can be separated by commas
 * @param [ui-refresh] {expression} Watch expression and refire plugin on changes
 *
 * @example <input ui-jq="datepicker" ui-options="{showOn:'click'},secondParameter,thirdParameter" ui-refresh="iChange">
 */
window.app_uijq = angular.module("ui.jq", ["ui.load"])
    .value("uiJqConfig", {})
    .directive("uiJq", ["uiJqConfig", "JQ_CONFIG", "uiLoad", "$timeout", function uiJqInjectingFunction(uiJqConfig, JQ_CONFIG, uiLoad, $timeout) {
        return {
            restrict: "A",
            compile: function uiJqCompilingFunction(tElm, tAttrs) {
                if (!angular.isFunction(tElm[tAttrs.uiJq]) && !JQ_CONFIG[tAttrs.uiJq]) {
                    throw new Error('ui-jq: The "' + tAttrs.uiJq + '" function does not exist');
                }

                var options = uiJqConfig && uiJqConfig[tAttrs.uiJq];

                return function uiJqLinkingFunction(scope, elm, attrs) {
                    function getOptions() {
                        var linkOptions = [];

                        // If ui-options are passed, merge (or override) them onto global defaults and pass to the jQuery method
                        if (attrs.uiOptions) {
                            linkOptions = scope.$eval("[" + attrs.uiOptions + "]");

                            if (angular.isObject(options) && angular.isObject(linkOptions[0])) {
                                linkOptions[0] = angular.extend({}, options, linkOptions[0]);
                            }
                        }
                        else if (options) {
                            linkOptions = [options];
                        }

                        return linkOptions;
                    }

                    // If change compatibility is enabled, the form input's "change" event will trigger an "input" event
                    if (attrs.ngModel && elm.is("select,input,textarea")) {
                        elm.bind("change", function() {
                            elm.trigger("input");
                        });
                    }

                    // Call jQuery method and pass relevant options
                    function callPlugin() {
                        $timeout(function() {
                            elm[attrs.uiJq].apply(elm, getOptions());
                        }, 0, false);
                    }

                    function refresh() {
                        // If ui-refresh is used, re-fire the the method upon every change
                        if (attrs.uiRefresh) {
                            scope.$watch(attrs.uiRefresh, function() {
                                callPlugin();
                            });
                        }
                    }

                    if (JQ_CONFIG[attrs.uiJq]) {
                        uiLoad.load(JQ_CONFIG[attrs.uiJq]).then(function() {
                            callPlugin();
                            refresh();
                        }).catch(function() {});
                    }
                    else {
                        callPlugin();
                        refresh();
                    }
                };
            }
        };
    }]);

})();